package ch01.text00.tx11.demo02;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author V
 * @date 2025-03-24
 */
public class BeanUtil {
    /**
     * 1、设置何意对象的属性值
     *
     * @param bean         Bean对象
     * @param propertyName 属性名称
     * @param value        属性值
     */
    public static void setProperty(Object bean, String propertyName, Object value) {
        try {
            PropertyDescriptor pd = new PropertyDescriptor(propertyName, bean.getClass());

            Method setter = pd.getWriteMethod();

            if (setter != null) {
                setter.invoke(bean,value);
            }
        } catch (IntrospectionException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 2、获取任意对象的属性值
     *
     * @param bean         Bean对象
     * @param propertyName 属性名称
     * @return 属性值
     */
    public static Object getProperty(Object bean, String propertyName) {
        try {
            PropertyDescriptor pd = new PropertyDescriptor(propertyName, bean.getClass());

            return pd.getReadMethod().invoke(bean);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 3、复制某个对象的属性值到另一个对象中
     *
     * @param sourceBean 源 Bean 对象
     * @param targetBean 目标 Bean 对象
     */
    public static void copyProperties(Object sourceBean, Object targetBean) {
        try {
            // 获取 bean对象的 BeanInfo对象
            BeanInfo sourceBeanInfo = Introspector.getBeanInfo(sourceBean.getClass(), Object.class);

            // 获取 Bean 对象中的所有 属性
            PropertyDescriptor[] PropertyDescriptors = sourceBeanInfo.getPropertyDescriptors();

            for (PropertyDescriptor pd : PropertyDescriptors) {
                // 获取属性名称
                String pdname = pd.getName();
                // 获取属性值
                Object propertyValue = getProperty(sourceBean, pdname);
                // 给目标对象赋值
                setProperty(targetBean, pdname, propertyValue);
            }
        } catch (IntrospectionException e) {
            throw new RuntimeException(e);
        }
    }
}
